package com.gitee.srurl.core.api.impl.id;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.gitee.srurl.core.annotation.ApiImpl;
import com.gitee.srurl.core.api.IConfigCache;
import com.gitee.srurl.core.api.IUniqueIdGenerate;
import com.gitee.srurl.core.constant.ApiTypeConstant;
import com.gitee.srurl.core.properties.SidProperties;
import com.gitee.srurl.core.util.JacksonUtil;
import com.gitee.srurl.sid.domain.SidData;
import com.gitee.srurl.sid.domain.SidReportData;
import com.gitee.srurl.sid.gen.Sid;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Optional;

/**
 * sid（short id）生成
 *
 * @author zxw
 * @date 2023/4/26 21:56
 */
@Slf4j
@ApiImpl(ApiTypeConstant.UniqueIdGenerate.SID)
public class SidGenerate implements IUniqueIdGenerate {

    private final Sid sid;

    public SidGenerate(SidProperties sidProperties) {
        this(null, sidProperties);
    }

    public SidGenerate(List<IConfigCache> configCacheList, SidProperties sidProperties) {

        if (sidProperties == null) {
            log.error("初始化sid参数不能为空！");
            throw new IllegalArgumentException("初始化id生成器ID参数不能为空！");
        }

        SidReportData sidReportData = null;
        if (CollectionUtil.isNotEmpty(configCacheList)) {
            // 去读配置文件参数
            for (IConfigCache configCache : configCacheList) {
                byte[] read = configCache.read(StrUtil.format("sid/sid.json", sidProperties.getWorkerId()));
                if (read != null) {
                    SidReportData sidReportDataTemp = JacksonUtil.parseObject(read, new TypeReference<>() {
                    });
                    // 获取最高版本号的那个
                    if (sidReportData == null || sidReportData.getVersion() == null) {
                        sidReportData = sidReportDataTemp;
                    } else {
                        Long version = sidReportData.getVersion();
                        Long tempVersion = Optional.ofNullable(sidReportDataTemp.getVersion()).orElse(-1L);
                        if (version < tempVersion) {
                            sidReportData = sidReportDataTemp;
                        }
                    }
                }
            }
        }

        long startYear = sidReportData == null ? sidProperties.getStartYear() : sidReportData.getStartYear();
        long lastTimeBorrow = sidReportData == null ? -1 : sidReportData.getLastTimeBorrow();
        long lastTime = sidReportData == null ? -1 : sidReportData.getLastTime();
        long sequenceBorrow = sidReportData == null ? -1 : sidReportData.getSequenceBorrow();
        long sequence = sidReportData == null ? -1 : sidReportData.getSequence();

        SidData sidData = SidData.builder()
                .startYear(startYear)
                .allowClockBackwards(sidProperties.getAllowClockBackwards())
                .lastTime(lastTime)
                .lastTimeBorrow(lastTimeBorrow)
                .sequenceBorrow(sequenceBorrow)
                .sequence(sequence)
                .build();

        sid = new Sid(sidData);
    }

    @Override
    public long getId() {

        return sid.nextId();
    }
}
